package com.hjy.core.nacos;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.hjy.common.enumeration.RpcError;
import com.hjy.common.exception.RpcException;
import com.hjy.core.loadBalance.LoadBalancer;
import com.hjy.core.loadBalance.RandomLoadBalancer;
import com.hjy.core.loadBalance.RoundRobinLoadBalancer;

import java.net.InetSocketAddress;
import java.util.List;

/**
 * nacos 的注册方式
 */
public class NacosServiceRegistry implements ServiceRegistry {
    private static final String SERVER_ADDR = "127.0.0.1:8848";
    private static final NamingService namingService;
    private LoadBalancer loadBalancer;

    static {
        try {
            namingService = NamingFactory.createNamingService(SERVER_ADDR);
        } catch (NacosException e) {
            System.err.println("连接到Nacos时有错误发生:" + e.getErrMsg());
            throw new RpcException(RpcError.FAILED_TO_CONNECT_TO_SERVICE_REGISTRY);
        }
    }

    public NacosServiceRegistry(LoadBalancer loadBalancer) {
        if (loadBalancer == null) this.loadBalancer = new RandomLoadBalancer();
        else this.loadBalancer = loadBalancer;
    }

    public NacosServiceRegistry() {
        // 默认使用轮转算法
        this.loadBalancer = new RoundRobinLoadBalancer();
    }


    @Override
    public void register(String serviceName, InetSocketAddress inetSocketAddress) {
        // 向 nacos 注册服务
        try {
            namingService.registerInstance(serviceName, inetSocketAddress.getHostName(), inetSocketAddress.getPort());
        } catch (NacosException e) {
            System.err.println("连接到Nacos时有错误发生:" + e.getErrMsg());
            throw new RpcException(RpcError.REGISTER_SERVICE_FAILED);
        }
    }

    @Override
    public InetSocketAddress lookupService(String serviceName) {
        try {
            List<Instance> instances = namingService.getAllInstances(serviceName);
            // TODO 这里需要负载均衡
            // 获得提供某个服务的所有提供者的列表
            Instance instance = loadBalancer.select(instances);
            return new InetSocketAddress(instance.getIp(), instance.getPort());
        } catch (NacosException e) {
            throw new RuntimeException(e);
        }
    }
}
